{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "be1b37e0-dfe3-4f3a-8fc1-7b8bf6d24a1c",
   "metadata": {},
   "source": [
    "### Online /Incremental Machine Learning Tools\n",
    "+ Offline ML Learning : it means we have a batch of data, and we optimize an equation to make a prediction \n",
    "+ Online ML learning: used when we have streaming data, where we want to process one sample of data at a time.\n",
    "    - real-time data one observation at a time\n",
    "    - we update our estimates as each new data point arrives rather than waiting until “the end” (which may never occur)\n",
    "+ Incremental learning is a method of machine learning in which input data is continuously used to extend the existing model's knowledge i.e. to further train the model. \n",
    "+ It represents a dynamic technique of supervised learning and unsupervised learning that can be applied when training data becomes available gradually over time or its size is out of system memory limits.\n",
    "+ The AIM\n",
    "    - for the learning model to adapt to new data without forgetting its existing knowledge.\n",
    "\n",
    "\n",
    "\n",
    "#### Tools For Incremental or Online ML\n",
    "+ River\n",
    "    - Creme\n",
    "    - Scikit-Multiflow\n",
    "+ MOA\n",
    "+ SAMOA\n",
    "+ StreamDB (spark streaming)\n",
    "\n",
    "#### Usefulness\n",
    "+ For Online ML \n",
    "+ For ml on streaming data\n",
    "\n",
    "### Challenges\n",
    "+ Difficult to manage\n",
    "    - Highly Adaptive\n",
    "+ More Research Grade\n",
    "\n",
    "\n",
    "\n",
    "#### Installation\n",
    "+ pip install river\n",
    "+ pip install creme\n",
    "+ pip install scikit-multiflow"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ed43a93b-74c2-4e5d-ad22-98ab721b8a54",
   "metadata": {},
   "source": [
    "### Incremental /Online Machine Learning with River"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "4f4076bb-aa16-4d07-8ee9-ba0c449e3dc6",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "7d12ad0d-ef02-43ea-adbd-8f58977dcdcd",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Load ML Pkgs\n",
    "import river"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "5d51c15e-06e8-451e-9235-ec8e52893b4c",
   "metadata": {
    "collapsed": true,
    "jupyter": {
     "outputs_hidden": true
    },
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['__all__',\n",
       " '__builtins__',\n",
       " '__cached__',\n",
       " '__doc__',\n",
       " '__file__',\n",
       " '__loader__',\n",
       " '__name__',\n",
       " '__package__',\n",
       " '__path__',\n",
       " '__spec__',\n",
       " '__version__',\n",
       " 'anomaly',\n",
       " 'base',\n",
       " 'cluster',\n",
       " 'compat',\n",
       " 'compose',\n",
       " 'datasets',\n",
       " 'drift',\n",
       " 'dummy',\n",
       " 'ensemble',\n",
       " 'evaluate',\n",
       " 'expert',\n",
       " 'facto',\n",
       " 'feature_extraction',\n",
       " 'feature_selection',\n",
       " 'imblearn',\n",
       " 'linear_model',\n",
       " 'meta',\n",
       " 'metrics',\n",
       " 'multiclass',\n",
       " 'multioutput',\n",
       " 'naive_bayes',\n",
       " 'neighbors',\n",
       " 'neural_net',\n",
       " 'optim',\n",
       " 'preprocessing',\n",
       " 'proba',\n",
       " 'reco',\n",
       " 'stats',\n",
       " 'stream',\n",
       " 'synth',\n",
       " 'time_series',\n",
       " 'tree',\n",
       " 'utils']"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Method\n",
    "dir(river)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "a81a881f-c4ff-4789-af28-f935897f6eef",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Load Estimators\n",
    "from river.linear_model import LogisticRegression\n",
    "from river.naive_bayes import MultinomialNB\n",
    "from river.feature_extraction import BagOfWords,TFIDF\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "852ea480-3664-4ec8-8f11-fb8168c92f7b",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "def get_all_attributes(package):\n",
    "    subpackages = []\n",
    "    submodules = []\n",
    "    for i in dir(package):\n",
    "        if str(i) not in [\"__all__\", \"__builtins__\", \"__cached__\", \"__doc__\", \"__file__\", \"__loader__\", \"__name__\", \"__package__\", \"__path__\", \"__pdoc__\", \"__spec__\", \"__version__\"]:\n",
    "            subpackages.append(i)\n",
    "            res = [j for j in dir(eval(\"river.{}\".format(i)))]\n",
    "            submodules.append(res)\n",
    "    df = pd.DataFrame(submodules)\n",
    "    # Transpose\n",
    "    df = df.T\n",
    "    df.columns = subpackages\n",
    "    res_df = df.dropna()\n",
    "    return res_df\n",
    "           \n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "d8ea68e5-efd1-456b-84ca-3f35d83b1e48",
   "metadata": {},
   "outputs": [],
   "source": [
    "river_df = get_all_attributes(river)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "64873adb-0176-4bac-9a95-0bf47f1f2dfc",
   "metadata": {
    "collapsed": true,
    "jupyter": {
     "outputs_hidden": true
    },
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>anomaly</th>\n",
       "      <th>base</th>\n",
       "      <th>cluster</th>\n",
       "      <th>compat</th>\n",
       "      <th>compose</th>\n",
       "      <th>datasets</th>\n",
       "      <th>drift</th>\n",
       "      <th>dummy</th>\n",
       "      <th>ensemble</th>\n",
       "      <th>evaluate</th>\n",
       "      <th>...</th>\n",
       "      <th>optim</th>\n",
       "      <th>preprocessing</th>\n",
       "      <th>proba</th>\n",
       "      <th>reco</th>\n",
       "      <th>stats</th>\n",
       "      <th>stream</th>\n",
       "      <th>synth</th>\n",
       "      <th>time_series</th>\n",
       "      <th>tree</th>\n",
       "      <th>utils</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>HalfSpaceTrees</td>\n",
       "      <td>AnomalyDetector</td>\n",
       "      <td>CluStream</td>\n",
       "      <td>River2SKLClassifier</td>\n",
       "      <td>Discard</td>\n",
       "      <td>AirlinePassengers</td>\n",
       "      <td>ADWIN</td>\n",
       "      <td>NoChangeClassifier</td>\n",
       "      <td>ADWINBaggingClassifier</td>\n",
       "      <td>Track</td>\n",
       "      <td>...</td>\n",
       "      <td>AMSGrad</td>\n",
       "      <td>AdaptiveStandardScaler</td>\n",
       "      <td>Gaussian</td>\n",
       "      <td>Baseline</td>\n",
       "      <td>AbsMax</td>\n",
       "      <td>Cache</td>\n",
       "      <td>Agrawal</td>\n",
       "      <td>Detrender</td>\n",
       "      <td>ExtremelyFastDecisionTreeClassifier</td>\n",
       "      <td>Histogram</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>__all__</td>\n",
       "      <td>Base</td>\n",
       "      <td>DBSTREAM</td>\n",
       "      <td>River2SKLClusterer</td>\n",
       "      <td>FuncTransformer</td>\n",
       "      <td>Bananas</td>\n",
       "      <td>DDM</td>\n",
       "      <td>PriorClassifier</td>\n",
       "      <td>AdaBoostClassifier</td>\n",
       "      <td>__all__</td>\n",
       "      <td>...</td>\n",
       "      <td>AdaBound</td>\n",
       "      <td>Binarizer</td>\n",
       "      <td>Multinomial</td>\n",
       "      <td>BiasedMF</td>\n",
       "      <td>AutoCorr</td>\n",
       "      <td>__all__</td>\n",
       "      <td>AnomalySine</td>\n",
       "      <td>GroupDetrender</td>\n",
       "      <td>HoeffdingAdaptiveTreeClassifier</td>\n",
       "      <td>SDFT</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>__builtins__</td>\n",
       "      <td>Classifier</td>\n",
       "      <td>DenStream</td>\n",
       "      <td>River2SKLRegressor</td>\n",
       "      <td>Grouper</td>\n",
       "      <td>Bikes</td>\n",
       "      <td>EDDM</td>\n",
       "      <td>StatisticRegressor</td>\n",
       "      <td>AdaptiveRandomForestClassifier</td>\n",
       "      <td>__builtins__</td>\n",
       "      <td>...</td>\n",
       "      <td>AdaDelta</td>\n",
       "      <td>FeatureHasher</td>\n",
       "      <td>__all__</td>\n",
       "      <td>FunkMF</td>\n",
       "      <td>BayesianMean</td>\n",
       "      <td>__builtins__</td>\n",
       "      <td>ConceptDriftStream</td>\n",
       "      <td>SNARIMAX</td>\n",
       "      <td>HoeffdingAdaptiveTreeRegressor</td>\n",
       "      <td>Skyline</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>__cached__</td>\n",
       "      <td>Clusterer</td>\n",
       "      <td>KMeans</td>\n",
       "      <td>River2SKLTransformer</td>\n",
       "      <td>Pipeline</td>\n",
       "      <td>ChickWeights</td>\n",
       "      <td>HDDM_A</td>\n",
       "      <td>__all__</td>\n",
       "      <td>AdaptiveRandomForestRegressor</td>\n",
       "      <td>__cached__</td>\n",
       "      <td>...</td>\n",
       "      <td>AdaGrad</td>\n",
       "      <td>LDA</td>\n",
       "      <td>__builtins__</td>\n",
       "      <td>RandomNormal</td>\n",
       "      <td>Bivariate</td>\n",
       "      <td>__cached__</td>\n",
       "      <td>Friedman</td>\n",
       "      <td>__all__</td>\n",
       "      <td>HoeffdingTreeClassifier</td>\n",
       "      <td>SortedWindow</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>__doc__</td>\n",
       "      <td>DriftDetector</td>\n",
       "      <td>STREAMKMeans</td>\n",
       "      <td>SKL2RiverClassifier</td>\n",
       "      <td>Renamer</td>\n",
       "      <td>CreditCard</td>\n",
       "      <td>HDDM_W</td>\n",
       "      <td>__builtins__</td>\n",
       "      <td>BaggingClassifier</td>\n",
       "      <td>__doc__</td>\n",
       "      <td>...</td>\n",
       "      <td>AdaMax</td>\n",
       "      <td>MaxAbsScaler</td>\n",
       "      <td>__cached__</td>\n",
       "      <td>__all__</td>\n",
       "      <td>Count</td>\n",
       "      <td>__doc__</td>\n",
       "      <td>FriedmanDrift</td>\n",
       "      <td>__builtins__</td>\n",
       "      <td>HoeffdingTreeRegressor</td>\n",
       "      <td>VectorDict</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>__file__</td>\n",
       "      <td>EnsembleMixin</td>\n",
       "      <td>__all__</td>\n",
       "      <td>SKL2RiverRegressor</td>\n",
       "      <td>Select</td>\n",
       "      <td>Elec2</td>\n",
       "      <td>KSWIN</td>\n",
       "      <td>__cached__</td>\n",
       "      <td>BaggingRegressor</td>\n",
       "      <td>__file__</td>\n",
       "      <td>...</td>\n",
       "      <td>Adam</td>\n",
       "      <td>MinMaxScaler</td>\n",
       "      <td>__doc__</td>\n",
       "      <td>__builtins__</td>\n",
       "      <td>Cov</td>\n",
       "      <td>__file__</td>\n",
       "      <td>Hyperplane</td>\n",
       "      <td>__cached__</td>\n",
       "      <td>LabelCombinationHoeffdingTreeClassifier</td>\n",
       "      <td>Window</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>__loader__</td>\n",
       "      <td>Estimator</td>\n",
       "      <td>__builtins__</td>\n",
       "      <td>__all__</td>\n",
       "      <td>SelectType</td>\n",
       "      <td>HTTP</td>\n",
       "      <td>PageHinkley</td>\n",
       "      <td>__doc__</td>\n",
       "      <td>LeveragingBaggingClassifier</td>\n",
       "      <td>__loader__</td>\n",
       "      <td>...</td>\n",
       "      <td>Averager</td>\n",
       "      <td>Normalizer</td>\n",
       "      <td>__file__</td>\n",
       "      <td>__cached__</td>\n",
       "      <td>EWMean</td>\n",
       "      <td>__loader__</td>\n",
       "      <td>LED</td>\n",
       "      <td>__doc__</td>\n",
       "      <td>__all__</td>\n",
       "      <td>__all__</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>__name__</td>\n",
       "      <td>MiniBatchClassifier</td>\n",
       "      <td>__cached__</td>\n",
       "      <td>__annotations__</td>\n",
       "      <td>TransformerUnion</td>\n",
       "      <td>Higgs</td>\n",
       "      <td>__all__</td>\n",
       "      <td>__file__</td>\n",
       "      <td>SRPClassifier</td>\n",
       "      <td>__name__</td>\n",
       "      <td>...</td>\n",
       "      <td>FTRLProximal</td>\n",
       "      <td>OneHotEncoder</td>\n",
       "      <td>__loader__</td>\n",
       "      <td>__doc__</td>\n",
       "      <td>EWVar</td>\n",
       "      <td>__name__</td>\n",
       "      <td>LEDDrift</td>\n",
       "      <td>__file__</td>\n",
       "      <td>__builtins__</td>\n",
       "      <td>__builtins__</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>__package__</td>\n",
       "      <td>MiniBatchRegressor</td>\n",
       "      <td>__doc__</td>\n",
       "      <td>__builtins__</td>\n",
       "      <td>__all__</td>\n",
       "      <td>ImageSegments</td>\n",
       "      <td>__builtins__</td>\n",
       "      <td>__loader__</td>\n",
       "      <td>__all__</td>\n",
       "      <td>__package__</td>\n",
       "      <td>...</td>\n",
       "      <td>Momentum</td>\n",
       "      <td>PreviousImputer</td>\n",
       "      <td>__name__</td>\n",
       "      <td>__file__</td>\n",
       "      <td>Entropy</td>\n",
       "      <td>__package__</td>\n",
       "      <td>Logical</td>\n",
       "      <td>__loader__</td>\n",
       "      <td>__cached__</td>\n",
       "      <td>__cached__</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>__path__</td>\n",
       "      <td>MultiOutputMixin</td>\n",
       "      <td>__file__</td>\n",
       "      <td>__cached__</td>\n",
       "      <td>__builtins__</td>\n",
       "      <td>Insects</td>\n",
       "      <td>__cached__</td>\n",
       "      <td>__name__</td>\n",
       "      <td>__builtins__</td>\n",
       "      <td>__path__</td>\n",
       "      <td>...</td>\n",
       "      <td>Nadam</td>\n",
       "      <td>RobustScaler</td>\n",
       "      <td>__package__</td>\n",
       "      <td>__loader__</td>\n",
       "      <td>IQR</td>\n",
       "      <td>__path__</td>\n",
       "      <td>Mixed</td>\n",
       "      <td>__name__</td>\n",
       "      <td>__doc__</td>\n",
       "      <td>__doc__</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>__spec__</td>\n",
       "      <td>Regressor</td>\n",
       "      <td>__loader__</td>\n",
       "      <td>__doc__</td>\n",
       "      <td>__cached__</td>\n",
       "      <td>MaliciousURL</td>\n",
       "      <td>__doc__</td>\n",
       "      <td>__package__</td>\n",
       "      <td>__cached__</td>\n",
       "      <td>__spec__</td>\n",
       "      <td>...</td>\n",
       "      <td>NesterovMomentum</td>\n",
       "      <td>StandardScaler</td>\n",
       "      <td>__path__</td>\n",
       "      <td>__name__</td>\n",
       "      <td>Kurtosis</td>\n",
       "      <td>__spec__</td>\n",
       "      <td>Mv</td>\n",
       "      <td>__package__</td>\n",
       "      <td>__file__</td>\n",
       "      <td>__file__</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>hst</td>\n",
       "      <td>SupervisedTransformer</td>\n",
       "      <td>__name__</td>\n",
       "      <td>__file__</td>\n",
       "      <td>__doc__</td>\n",
       "      <td>MovieLens100K</td>\n",
       "      <td>__file__</td>\n",
       "      <td>__spec__</td>\n",
       "      <td>__doc__</td>\n",
       "      <td>load_binary_clf_tracks</td>\n",
       "      <td>...</td>\n",
       "      <td>Optimizer</td>\n",
       "      <td>StatImputer</td>\n",
       "      <td>__spec__</td>\n",
       "      <td>__package__</td>\n",
       "      <td>Link</td>\n",
       "      <td>cache</td>\n",
       "      <td>Planes2D</td>\n",
       "      <td>__path__</td>\n",
       "      <td>__loader__</td>\n",
       "      <td>__loader__</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>12 rows × 33 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "           anomaly                   base       cluster                compat  \\\n",
       "0   HalfSpaceTrees        AnomalyDetector     CluStream   River2SKLClassifier   \n",
       "1          __all__                   Base      DBSTREAM    River2SKLClusterer   \n",
       "2     __builtins__             Classifier     DenStream    River2SKLRegressor   \n",
       "3       __cached__              Clusterer        KMeans  River2SKLTransformer   \n",
       "4          __doc__          DriftDetector  STREAMKMeans   SKL2RiverClassifier   \n",
       "5         __file__          EnsembleMixin       __all__    SKL2RiverRegressor   \n",
       "6       __loader__              Estimator  __builtins__               __all__   \n",
       "7         __name__    MiniBatchClassifier    __cached__       __annotations__   \n",
       "8      __package__     MiniBatchRegressor       __doc__          __builtins__   \n",
       "9         __path__       MultiOutputMixin      __file__            __cached__   \n",
       "10        __spec__              Regressor    __loader__               __doc__   \n",
       "11             hst  SupervisedTransformer      __name__              __file__   \n",
       "\n",
       "             compose           datasets         drift               dummy  \\\n",
       "0            Discard  AirlinePassengers         ADWIN  NoChangeClassifier   \n",
       "1    FuncTransformer            Bananas           DDM     PriorClassifier   \n",
       "2            Grouper              Bikes          EDDM  StatisticRegressor   \n",
       "3           Pipeline       ChickWeights        HDDM_A             __all__   \n",
       "4            Renamer         CreditCard        HDDM_W        __builtins__   \n",
       "5             Select              Elec2         KSWIN          __cached__   \n",
       "6         SelectType               HTTP   PageHinkley             __doc__   \n",
       "7   TransformerUnion              Higgs       __all__            __file__   \n",
       "8            __all__      ImageSegments  __builtins__          __loader__   \n",
       "9       __builtins__            Insects    __cached__            __name__   \n",
       "10        __cached__       MaliciousURL       __doc__         __package__   \n",
       "11           __doc__      MovieLens100K      __file__            __spec__   \n",
       "\n",
       "                          ensemble                evaluate  ...  \\\n",
       "0           ADWINBaggingClassifier                   Track  ...   \n",
       "1               AdaBoostClassifier                 __all__  ...   \n",
       "2   AdaptiveRandomForestClassifier            __builtins__  ...   \n",
       "3    AdaptiveRandomForestRegressor              __cached__  ...   \n",
       "4                BaggingClassifier                 __doc__  ...   \n",
       "5                 BaggingRegressor                __file__  ...   \n",
       "6      LeveragingBaggingClassifier              __loader__  ...   \n",
       "7                    SRPClassifier                __name__  ...   \n",
       "8                          __all__             __package__  ...   \n",
       "9                     __builtins__                __path__  ...   \n",
       "10                      __cached__                __spec__  ...   \n",
       "11                         __doc__  load_binary_clf_tracks  ...   \n",
       "\n",
       "               optim           preprocessing         proba          reco  \\\n",
       "0            AMSGrad  AdaptiveStandardScaler      Gaussian      Baseline   \n",
       "1           AdaBound               Binarizer   Multinomial      BiasedMF   \n",
       "2           AdaDelta           FeatureHasher       __all__        FunkMF   \n",
       "3            AdaGrad                     LDA  __builtins__  RandomNormal   \n",
       "4             AdaMax            MaxAbsScaler    __cached__       __all__   \n",
       "5               Adam            MinMaxScaler       __doc__  __builtins__   \n",
       "6           Averager              Normalizer      __file__    __cached__   \n",
       "7       FTRLProximal           OneHotEncoder    __loader__       __doc__   \n",
       "8           Momentum         PreviousImputer      __name__      __file__   \n",
       "9              Nadam            RobustScaler   __package__    __loader__   \n",
       "10  NesterovMomentum          StandardScaler      __path__      __name__   \n",
       "11         Optimizer             StatImputer      __spec__   __package__   \n",
       "\n",
       "           stats        stream               synth     time_series  \\\n",
       "0         AbsMax         Cache             Agrawal       Detrender   \n",
       "1       AutoCorr       __all__         AnomalySine  GroupDetrender   \n",
       "2   BayesianMean  __builtins__  ConceptDriftStream        SNARIMAX   \n",
       "3      Bivariate    __cached__            Friedman         __all__   \n",
       "4          Count       __doc__       FriedmanDrift    __builtins__   \n",
       "5            Cov      __file__          Hyperplane      __cached__   \n",
       "6         EWMean    __loader__                 LED         __doc__   \n",
       "7          EWVar      __name__            LEDDrift        __file__   \n",
       "8        Entropy   __package__             Logical      __loader__   \n",
       "9            IQR      __path__               Mixed        __name__   \n",
       "10      Kurtosis      __spec__                  Mv     __package__   \n",
       "11          Link         cache            Planes2D        __path__   \n",
       "\n",
       "                                       tree         utils  \n",
       "0       ExtremelyFastDecisionTreeClassifier     Histogram  \n",
       "1           HoeffdingAdaptiveTreeClassifier          SDFT  \n",
       "2            HoeffdingAdaptiveTreeRegressor       Skyline  \n",
       "3                   HoeffdingTreeClassifier  SortedWindow  \n",
       "4                    HoeffdingTreeRegressor    VectorDict  \n",
       "5   LabelCombinationHoeffdingTreeClassifier        Window  \n",
       "6                                   __all__       __all__  \n",
       "7                              __builtins__  __builtins__  \n",
       "8                                __cached__    __cached__  \n",
       "9                                   __doc__       __doc__  \n",
       "10                                 __file__      __file__  \n",
       "11                               __loader__    __loader__  \n",
       "\n",
       "[12 rows x 33 columns]"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "river_df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "86eb19ce-ff79-4561-8c1c-0bb1f54decd0",
   "metadata": {},
   "outputs": [],
   "source": [
    "#### Requirement\n",
    "+ list of tuple\n",
    "+ dictionary\n",
    "+ CSV\n",
    "    - list of tuples or dictionary record\n",
    "    - iter_csv\n",
    "    - iter_pandas"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "id": "49f666f0-a568-497f-b298-1edaaa7b222c",
   "metadata": {},
   "outputs": [],
   "source": [
    "### Data: Predict if a text if hardware or software related\n",
    "data = [(\"my unit test failed\",\"software\"),\n",
    "(\"tried the program, but it was buggy\",\"software\"),\n",
    "(\"i need a new power supply\",\"hardware\"),\n",
    "(\"the drive has a 2TB capacity\",\"hardware\"),\n",
    "(\"unit-tests\",\"software\"),\n",
    "(\"program\",\"software\"),\n",
    "(\"power supply\",\"hardware\"),\n",
    "(\"drive\",\"hardware\"),\n",
    "(\"it needs more memory\",\"hardware\"),\n",
    "(\"check the API\",\"software\"),\n",
    "(\"design the API\",\"software\"),\n",
    "(\"they need more CPU\",\"hardware\"),\n",
    "(\"code\",\"software\"),\n",
    "(\"i found some bugs in the code\",\"software\"),\n",
    "(\"i swapped the memory\",\"hardware\"),\n",
    "(\"i tested the code\",\"software\")]\n",
    "\n",
    "test_data = [('he writes code daily','software'), \n",
    "             ('the disk is faulty','hardware'), \n",
    "             (\"refactor the code\",\"software\"),\n",
    "             ('no empty space on the drive','hardware')]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2c6b2733-5f45-404b-a9c7-b3aa8ce2c534",
   "metadata": {},
   "source": [
    "### Text classification\n",
    "+ vectorized the text\n",
    "    - CountVectorizer/ BagOfWords\n",
    "    - TFIDF\n",
    "+ build model on the go"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "id": "2f300d1c-10f9-4151-9112-f0464e6493e5",
   "metadata": {},
   "outputs": [],
   "source": [
    "#  Make a Pipeline\n",
    "from river.compose import Pipeline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "id": "00a2f540-5551-47fe-ac56-60f01b8ef460",
   "metadata": {},
   "outputs": [],
   "source": [
    "pipe_nb = Pipeline(('vectorizer',BagOfWords(lowercase=True)),('nb',MultinomialNB()))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "id": "4a17b519-37ca-411f-a97c-b187c9f2bd66",
   "metadata": {
    "collapsed": true,
    "jupyter": {
     "outputs_hidden": true
    },
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<html><body><div class=\"pipeline\"><details class=\"estimator\"><summary><pre class=\"estimator-name\">BagOfWords</pre></summary><code class=\"estimator-params\">\n",
       "{'lowercase': True,\n",
       " 'ngram_range': (1, 1),\n",
       " 'on': None,\n",
       " 'preprocessor': None,\n",
       " 'processing_steps': [&lt;function strip_accents_unicode at 0x7fa35a209dc0&gt;,\n",
       "                      &lt;method 'lower' of 'str' objects&gt;,\n",
       "                      &lt;built-in method findall of re.Pattern object at 0x7fa35529de00&gt;],\n",
       " 'strip_accents': True,\n",
       " 'tokenizer': &lt;built-in method findall of re.Pattern object at 0x7fa35529de00&gt;}\n",
       "\n",
       "</code></details><details class=\"estimator\"><summary><pre class=\"estimator-name\">MultinomialNB</pre></summary><code class=\"estimator-params\">\n",
       "{'alpha': 1.0,\n",
       " 'class_counts': Counter(),\n",
       " 'class_totals': Counter(),\n",
       " 'feature_counts': defaultdict(&lt;class 'collections.Counter'&gt;, {})}\n",
       "\n",
       "</code></details></div></body><style>\n",
       ".estimator {\n",
       "    padding: 1em;\n",
       "    border-style: solid;\n",
       "    background: white;\n",
       "}\n",
       "\n",
       ".pipeline {\n",
       "    display: flex;\n",
       "    flex-direction: column;\n",
       "    align-items: center;\n",
       "    background: linear-gradient(#000, #000) no-repeat center / 3px 100%;\n",
       "}\n",
       "\n",
       ".union {\n",
       "    display: flex;\n",
       "    flex-direction: row;\n",
       "    align-items: center;\n",
       "    justify-content: center;\n",
       "    padding: 1em;\n",
       "    border-style: solid;\n",
       "    background: white\n",
       "}\n",
       "\n",
       "/* Vertical spacing between steps */\n",
       "\n",
       ".estimator + .estimator,\n",
       ".estimator + .union,\n",
       ".union + .estimator {\n",
       "    margin-top: 2em;\n",
       "}\n",
       "\n",
       ".union > .estimator {\n",
       "    margin-top: 0;\n",
       "}\n",
       "\n",
       "/* Spacing within a union of estimators */\n",
       "\n",
       ".union >\n",
       ".estimator + .estimator,\n",
       ".pipeline + .estimator,\n",
       ".estimator + .pipeline,\n",
       ".pipeline + .pipeline {\n",
       "    margin-left: 1em;\n",
       "}\n",
       "\n",
       "/* Typography */\n",
       ".estimator-params {\n",
       "    display: block;\n",
       "    white-space: pre-wrap;\n",
       "    font-size: 120%;\n",
       "    margin-bottom: -1em;\n",
       "}\n",
       "\n",
       ".estimator > code {\n",
       "    background-color: white !important;\n",
       "}\n",
       "\n",
       ".estimator-name {\n",
       "    display: inline;\n",
       "    margin: 0;\n",
       "    font-size: 130%;\n",
       "}\n",
       "\n",
       "/* Toggle */\n",
       "\n",
       "summary {\n",
       "    display: flex;\n",
       "    align-items:center;\n",
       "    cursor: pointer;\n",
       "}\n",
       "\n",
       "summary > div {\n",
       "    width: 100%;\n",
       "}\n",
       "</style></html>"
      ],
      "text/plain": [
       "Pipeline (\n",
       "  BagOfWords (\n",
       "    on=None\n",
       "    strip_accents=True\n",
       "    lowercase=True\n",
       "    preprocessor=None\n",
       "    tokenizer=<built-in method findall of re.Pattern object at 0x7fa35529de00>\n",
       "    ngram_range=(1, 1)\n",
       "  ),\n",
       "  MultinomialNB (\n",
       "    alpha=1.\n",
       "  )\n",
       ")"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "### Visualize the Pipeline\n",
    "pipe_nb"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "id": "526c2ef5-7490-44c8-a31e-f5b1c683a26b",
   "metadata": {
    "collapsed": true,
    "jupyter": {
     "outputs_hidden": true
    },
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "OrderedDict([('vectorizer',\n",
       "              BagOfWords (\n",
       "                on=None\n",
       "                strip_accents=True\n",
       "                lowercase=True\n",
       "                preprocessor=None\n",
       "                tokenizer=<built-in method findall of re.Pattern object at 0x7fa35529de00>\n",
       "                ngram_range=(1, 1)\n",
       "              )),\n",
       "             ('nb',\n",
       "              MultinomialNB (\n",
       "                alpha=1.\n",
       "              ))])"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Get steps\n",
    "pipe_nb.steps"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "id": "3f8a8218-4786-4edc-88b4-346de5b59cb0",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Fit on our data\n",
    "# Learn one at a time\n",
    "# learn_one(for river)/ fit_one(for creme)\n",
    "# predict_one\n",
    "\n",
    "for text,label in data:\n",
    "#     print(label)\n",
    "    pipe_nb = pipe_nb.learn_one(text,label)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "id": "d777bd0f-acc2-4b40-b9cb-5102a53c8d87",
   "metadata": {
    "collapsed": true,
    "jupyter": {
     "outputs_hidden": true
    },
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<html><body><div class=\"pipeline\"><details class=\"estimator\"><summary><pre class=\"estimator-name\">BagOfWords</pre></summary><code class=\"estimator-params\">\n",
       "{'lowercase': True,\n",
       " 'ngram_range': (1, 1),\n",
       " 'on': None,\n",
       " 'preprocessor': None,\n",
       " 'processing_steps': [&lt;function strip_accents_unicode at 0x7fa35a209dc0&gt;,\n",
       "                      &lt;method 'lower' of 'str' objects&gt;,\n",
       "                      &lt;built-in method findall of re.Pattern object at 0x7fa35529de00&gt;],\n",
       " 'strip_accents': True,\n",
       " 'tokenizer': &lt;built-in method findall of re.Pattern object at 0x7fa35529de00&gt;}\n",
       "\n",
       "</code></details><details class=\"estimator\"><summary><pre class=\"estimator-name\">MultinomialNB</pre></summary><code class=\"estimator-params\">\n",
       "{'alpha': 1.0,\n",
       " 'class_counts': Counter({'software': 9, 'hardware': 7}),\n",
       " 'class_totals': Counter({'software': 30, 'hardware': 23}),\n",
       " 'feature_counts': defaultdict(&lt;class 'collections.Counter'&gt;,\n",
       "                               {'2tb': Counter({'hardware': 1}),\n",
       "                                'api': Counter({'software': 2}),\n",
       "                                'buggy': Counter({'software': 1}),\n",
       "                                'bugs': Counter({'software': 1}),\n",
       "                                'but': Counter({'software': 1}),\n",
       "                                'capacity': Counter({'hardware': 1}),\n",
       "                                'check': Counter({'software': 1}),\n",
       "                                'code': Counter({'software': 3}),\n",
       "                                'cpu': Counter({'hardware': 1}),\n",
       "                                'design': Counter({'software': 1}),\n",
       "                                'drive': Counter({'hardware': 2}),\n",
       "                                'failed': Counter({'software': 1}),\n",
       "                                'found': Counter({'software': 1}),\n",
       "                                'has': Counter({'hardware': 1}),\n",
       "                                'in': Counter({'software': 1}),\n",
       "                                'it': Counter({'software': 1, 'hardware': 1}),\n",
       "                                'memory': Counter({'hardware': 2}),\n",
       "                                'more': Counter({'hardware': 2}),\n",
       "                                'my': Counter({'software': 1}),\n",
       "                                'need': Counter({'hardware': 2}),\n",
       "                                'needs': Counter({'hardware': 1}),\n",
       "                                'new': Counter({'hardware': 1}),\n",
       "                                'power': Counter({'hardware': 2}),\n",
       "                                'program': Counter({'software': 2}),\n",
       "                                'some': Counter({'software': 1}),\n",
       "                                'supply': Counter({'hardware': 2}),\n",
       "                                'swapped': Counter({'hardware': 1}),\n",
       "                                'test': Counter({'software': 1}),\n",
       "                                'tested': Counter({'software': 1}),\n",
       "                                'tests': Counter({'software': 1}),\n",
       "                                'the': Counter({'software': 5, 'hardware': 2}),\n",
       "                                'they': Counter({'hardware': 1}),\n",
       "                                'tried': Counter({'software': 1}),\n",
       "                                'unit': Counter({'software': 2}),\n",
       "                                'was': Counter({'software': 1})})}\n",
       "\n",
       "</code></details></div></body><style>\n",
       ".estimator {\n",
       "    padding: 1em;\n",
       "    border-style: solid;\n",
       "    background: white;\n",
       "}\n",
       "\n",
       ".pipeline {\n",
       "    display: flex;\n",
       "    flex-direction: column;\n",
       "    align-items: center;\n",
       "    background: linear-gradient(#000, #000) no-repeat center / 3px 100%;\n",
       "}\n",
       "\n",
       ".union {\n",
       "    display: flex;\n",
       "    flex-direction: row;\n",
       "    align-items: center;\n",
       "    justify-content: center;\n",
       "    padding: 1em;\n",
       "    border-style: solid;\n",
       "    background: white\n",
       "}\n",
       "\n",
       "/* Vertical spacing between steps */\n",
       "\n",
       ".estimator + .estimator,\n",
       ".estimator + .union,\n",
       ".union + .estimator {\n",
       "    margin-top: 2em;\n",
       "}\n",
       "\n",
       ".union > .estimator {\n",
       "    margin-top: 0;\n",
       "}\n",
       "\n",
       "/* Spacing within a union of estimators */\n",
       "\n",
       ".union >\n",
       ".estimator + .estimator,\n",
       ".pipeline + .estimator,\n",
       ".estimator + .pipeline,\n",
       ".pipeline + .pipeline {\n",
       "    margin-left: 1em;\n",
       "}\n",
       "\n",
       "/* Typography */\n",
       ".estimator-params {\n",
       "    display: block;\n",
       "    white-space: pre-wrap;\n",
       "    font-size: 120%;\n",
       "    margin-bottom: -1em;\n",
       "}\n",
       "\n",
       ".estimator > code {\n",
       "    background-color: white !important;\n",
       "}\n",
       "\n",
       ".estimator-name {\n",
       "    display: inline;\n",
       "    margin: 0;\n",
       "    font-size: 130%;\n",
       "}\n",
       "\n",
       "/* Toggle */\n",
       "\n",
       "summary {\n",
       "    display: flex;\n",
       "    align-items:center;\n",
       "    cursor: pointer;\n",
       "}\n",
       "\n",
       "summary > div {\n",
       "    width: 100%;\n",
       "}\n",
       "</style></html>"
      ],
      "text/plain": [
       "Pipeline (\n",
       "  BagOfWords (\n",
       "    on=None\n",
       "    strip_accents=True\n",
       "    lowercase=True\n",
       "    preprocessor=None\n",
       "    tokenizer=<built-in method findall of re.Pattern object at 0x7fa35529de00>\n",
       "    ngram_range=(1, 1)\n",
       "  ),\n",
       "  MultinomialNB (\n",
       "    alpha=1.\n",
       "  )\n",
       ")"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pipe_nb"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "id": "aa115b6f-2f6c-4e17-a251-d4d7412b17c1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'software'"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Make Prediction\n",
    "pipe_nb.predict_one(\"I built an API\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "id": "25a6d2e3-93db-4e6b-bab2-4fc1a240b26a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'software': 0.732646964375691, 'hardware': 0.2673530356243093}"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Make Prediction\n",
    "pipe_nb.predict_proba_one(\"I built an API\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "id": "8036d962-b32b-4efa-b546-1c6a6e9a892b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'software'"
      ]
     },
     "execution_count": 57,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Other \n",
    "pipe_nb.predict_one(\"the hard drive  in the computer is damaged\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "id": "21683eb7-b325-48ac-9707-707ab70bcfc0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'software': 0.5794679370463756, 'hardware': 0.4205320629536237}"
      ]
     },
     "execution_count": 58,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Prediction Proba\n",
    "# Other \n",
    "pipe_nb.predict_proba_one(\"the hard drive  in the computer is damaged\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "61b01567-fe11-4e23-ae71-d2be3274eabc",
   "metadata": {},
   "outputs": [],
   "source": [
    "### Evaluate & Classification\n",
    "+ Accuracy\n",
    "+ Precision/F1,Recall on a prediction"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "id": "1243c2dc-3a72-4079-9395-f9d3c9e26bea",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[('he writes code daily', 'software'),\n",
       " ('the disk is faulty', 'hardware'),\n",
       " ('refactor the code', 'software'),\n",
       " ('no empty space on the drive', 'hardware')]"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "id": "65a815fc-dc0f-4be1-b4e2-768a59f92c40",
   "metadata": {
    "collapsed": true,
    "jupyter": {
     "outputs_hidden": true
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "he writes code daily\n",
      "the disk is faulty\n",
      "refactor the code\n",
      "no empty space on the drive\n"
     ]
    }
   ],
   "source": [
    "y_pred = []\n",
    "for x,y in test_data:\n",
    "    print(x)\n",
    "    res = pipe_nb.predict_one(x)\n",
    "    y_pred.append(res)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "id": "2a7f8d4d-d955-4934-b4cc-d131a0a7fb03",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Classification\n",
    "from river.metrics import ClassificationReport"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "id": "1656a4d3-2092-4bd1-87ad-8c82ab756aef",
   "metadata": {},
   "outputs": [],
   "source": [
    "report = ClassificationReport()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "id": "f1a6ccff-b995-4951-8d73-e01b5784d35d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "he writes code daily\n",
      "the disk is faulty\n",
      "refactor the code\n",
      "no empty space on the drive\n"
     ]
    }
   ],
   "source": [
    "# Get y_true/y_test\n",
    "y_pred = []\n",
    "y_test = []\n",
    "for x,y in test_data:\n",
    "    print(x)\n",
    "    res = pipe_nb.predict_one(x)\n",
    "    y_pred.append(res)\n",
    "    y_test.append(y)\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "id": "e058883f-3400-46cc-871a-59ab5b2d6041",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['software', 'hardware', 'software', 'hardware']\n",
      "['software', 'software', 'software', 'hardware']\n"
     ]
    }
   ],
   "source": [
    "print(y_test)\n",
    "print(y_pred)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "id": "8b6b4750-8990-4ee0-a6ba-2b7248011a22",
   "metadata": {},
   "outputs": [],
   "source": [
    "for yt,yp in zip(y_test,y_pred):\n",
    "    report = report.update(yt,yp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "id": "9fa5aaf5-bbdd-4f13-b837-7854210f115a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "           Precision   Recall   F1      Support  \n",
       "                                                 \n",
       "hardware       1.000    0.500   0.667         2  \n",
       "software       0.667    1.000   0.800         2  \n",
       "                                                 \n",
       "   Macro       0.833    0.750   0.733            \n",
       "   Micro       0.750    0.750   0.750            \n",
       "Weighted       0.833    0.750   0.733            \n",
       "\n",
       "                 75.0% accuracy                  "
      ]
     },
     "execution_count": 71,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "report"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "id": "0df51b10-a7e2-4086-ab42-b83626df57b6",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Update the Model on the test data & Check Accuracy\n",
    "metric = river.metrics.Accuracy()\n",
    "for text,label in test_data:\n",
    "#     print(label)\n",
    "    y_pred_before = pipe_nb.predict_one(text)\n",
    "    metric = metric.update(label,y_pred_before)\n",
    "    # Has already learnt the pattern\n",
    "    pipe_nb = pipe_nb.learn_one(text,label)\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "id": "fc913bf0-9906-45d5-a265-60d048af4969",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Accuracy: 75.00%"
      ]
     },
     "execution_count": 74,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "metric"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "id": "0078fadb-29c0-455f-8814-dadf1cb9ac33",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Update the Model & Check Accuracy\n",
    "# On the train data: 100%\n",
    "metric2 = river.metrics.Accuracy()\n",
    "for text,label in data:\n",
    "#     print(label)\n",
    "    y_pred_before = pipe_nb.predict_one(text)\n",
    "    metric2 = metric2.update(label,y_pred_before)\n",
    "    pipe_nb = pipe_nb.learn_one(text,label)\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "id": "3c8b9743-6a7e-414a-a14d-92842aa41b99",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Accuracy: 100.00%"
      ]
     },
     "execution_count": 77,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "metric2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "id": "41ffd146-fe75-4011-99cf-2e4e38d5bf3d",
   "metadata": {},
   "outputs": [],
   "source": [
    "#### Thanks For Watching\n",
    "#### Jesus Saves @JCharisTech\n",
    "#### Jesse E.Agbe(JCharisTech) "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.1+"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
